import React, { useEffect, useState, useMemo, useReducer, useCallback } from 'react';
import isEqual from 'lodash.isequal';
import { useUpdateEffect } from '@umijs/hooks';

class UseTableInitState {
  // 当前页码
  current = 1;

  // 分页大小
  pageSize = 10;

  // 总页数
  total = 0;

  // 列表数据
  data = [];

  filters = {};

  sorter = {};
}
const reducer = (state, action) => {
  switch (action.type) {
    case 'updateState':
      return { ...state, ...action.payload };
    default:
      throw new Error();
  }
};

const useTableInitState = (options, onChange, deps) => {
  const _deps = Array.isArray(deps) ? deps : [];
  const initState = useMemo(() => new UseTableInitState(), []);

  const [state, dispatch] = useReducer(reducer, {
    ...initState,
    pageSize: 10,
  });

  const changeTable = useCallback(async (p, f = {}, s = {}) => {
    // antd table 的初始状态 filter 带有 null 字段，需要先去除后再比较
    const realFilter = { ...f };
    Object.entries(realFilter).forEach(item => {
      if (item[1] === null) {
        delete realFilter[item[0]];
      }
    });
    const realStateFilters = { ...state.filters };
    Object.entries(realStateFilters).forEach(item => {
      if (item[1] === null) {
        delete realStateFilters[item[0]];
      }
    });
    if (!s.order) {
      s.field = undefined;
      s.order = undefined;
    }
    const needReload =
      !isEqual(realFilter, realStateFilters) ||
      s.field !== state.sorter.field ||
      s.order !== state.sorter.order;

    let payload = {
      current: needReload ? 1 : p.current,
      pageSize: p.pageSize,
      filters: f,
      sorter: s,
    };
    dispatch({
      type: 'updateState',
      payload,
    });

    /**
     * @特殊值的处理对值的转换成对应接口字段:
     * @field     替换字段
     * @toString  是否需要数组转换为字符串
     * @return:
     */
    const replaceFieldFn = (field = {}, toString = false) => {
      let filters = {};

      Object.entries(f).forEach(item => {
        filters[field[item[0]] || item[0]] =
          (item[1] && (toString ? item[1].join(',') : item[1])) || undefined;
      });

      return filters;
    };
    onChange({ ...payload }, replaceFieldFn);
  });

  useUpdateEffect(() => {
    const params = {
      current: state.current,
      pageSize: state.pageSize,
    };
    if (state.filters) {
      params.filters = state.filters;
    }
    if (state.sorter) {
      params.sorter = state.sorter;
    }
    dispatch({
      type: 'updateState',
      payload: { ...params, ...options },
    });
  }, _deps);

  const result = {
    tableProps: {
      dataSource: state.data,
      onChange: changeTable,
      pagination: {
        current: state.current,
        showTotal: total => `共 ${total} 条`,
        pageSize: state.pageSize,
        total: state.total,
      },
    },
    sorter: state.sorter,
    filters: state.filters,
  };
  return result;
};
export default useTableInitState;
